<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <script>
    {
      const arr1 = [1, 2, 3]
      const arr2 = new Array(1, 2, 3)
      console.log(1, arr1 == arr2, typeof arr1, typeof arr2);
      // number string boolean null undefined Symbol
      // object function
      //number string boolean undefined object 
      function f() { }
      console.log(2, typeof f === 'function', typeof null === 'object', typeof undefined === 'undefined');
      console.log(3, typeof [] === 'object', typeof {} === 'object');
    }
    {
      const str1 = 'javascript'
      const str2 = new String('javascript')
      console.log(4, typeof str1 === 'string', typeof str2 === 'object');
    }
    {
      const obj1 = {}
      const obj2 = new Object()
      console.log(5, obj1, obj2, typeof obj1 === 'object', typeof obj2 === 'object');
      const arr1 = []
      const arr2 = new Array()
      console.log(6, arr1, arr2, typeof arr1 === 'object', typeof arr2 === 'object');
    }
    {
      const num = 1
      const str = 'str'
      const bool = true
      const empty = null
      const notDefined = undefined
      const sym = Symbol('sym')
      console.log(7, typeof num, typeof str, typeof bool, typeof empty, typeof notDefined, typeof sym);
    }
    // 直接调用和 new 调用的区别
    {
      function Teacher(name, age, subject, from) {
        this.name = name;
        this.mission = '传道受业解惑';
        this.age = age;
        this.subject = subject;
        this.from = from;
        this.teach = function () {
          console.log(`${name} 老师教 ${subject} 学科`);
        };
        // 上面这种通过this.xxx = xxx的方式直接向实例上添加的属性成为私有属性。
        var career = '前端'; // 这只是一个私有变量，不会和实例产生联系

      }
      // 普通函数执行：
      let t1 = Teacher('马宾', 18, 'js', '珠峰');
      console.log(t1); // undefined

      let t2 = new Teacher('姜文', 19, 'js', '珠峰');
      console.log(t2); // Teacher {naem:......}
    }
    {
      // 返回普通类型
      function Teacher(name, age, subject, from) {
        this.name = name;
        this.mission = '传道受业解惑';
        this.age = age;
        this.subject = subject;
        this.from = from;
        this.teach = function () {
          console.log(`${name} 老师教 ${subject} 学科`);
        };

        return 61; // 返回基本类型值
      }
      let t1 = new Teacher('马宾', 18, 'js', 'zf');
      console.log(t1); // Teacher {....}
    }
    {
      // 返回引用类型
      function Teacher(name, age, subject, from) {
        this.name = name;
        this.mission = '传道受业解惑';
        this.age = age;
        this.subject = subject;
        this.from = from;
        this.teach = function () {
          console.log(`${name} 老师教 ${subject} 学科`);
        };
        return { haha: '哈哈' }
      }

      let t2 = new Teacher('姜文', 19, 'js', '珠峰');
      console.log(t2); // {haha: ...}
    }
    // 原型模式
    {
      function Teacher(name, age, subject, from) {
        this.name = name;
        this.mission = '传道受业解惑';
        this.age = age;
        this.subject = subject;
        this.from = from;
        this.teach = function () {
          console.log(`${name} 老师教 ${subject} 学科`);
        };
      }

      let t1 = new Teacher('mabin', 18, 'js', 'zf');
      let t2 = new Teacher('mabin', 19, '架构', 'zf');

      t1.teach();
      t2.teach();
      console.log(t1.teach === t2.teach); // false 因为t1和t2是两个实例，而teach又是t1和t2的私有方法
      console.log(`t1`, t1.hasOwnProperty('teach'));

    }
    {
      const arr1 = [1, 3, 4]
      const arr2 = [4, 5, 6]
      console.log(arr1.push === arr2.push);
      function Teacher(name, age, subject, from) {
        this.name = name;
        this.mission = '传道受业解惑';
        this.age = age;
        this.subject = subject;
        this.from = from;
      }

      Teacher.prototype.teach = function () {
        console.log(`${this.name} 老师教 ${this.subject} 学科`);
      };

      console.log(Teacher.prototype);


      let t1 = new Teacher('mabin', 18, 'js', 'zf');
      let t2 = new Teacher('jiangwen', 19, '架构', 'zf');

      t1.teach();
      t2.teach();
      console.log(t1.teach === t2.teach); // true

      // 检测属性是公有还是私有
      const r1 = t1.hasOwnProperty('name')
      const r2 = t2.hasOwnProperty('teach')
      console.log(r1, r2);
      console.log(t1, t2, Teacher.prototype)
    }
  </script>
</body>

</html>